home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr27 / gs26.zip / GS_2ASC.PS < prev    next >
Text File  |  1993-05-05  |  12KB  |  383 lines

  1. %    Copyright (C) 1991, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2. %    Distributed by Free Software Foundation, Inc.
  3. %
  4. % This file is part of Ghostscript.
  5. %
  6. % Ghostscript is distributed in the hope that it will be useful, but
  7. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. % to anyone for the consequences of using it or for whether it serves any
  9. % particular purpose or works at all, unless he says so in writing.  Refer
  10. % to the Ghostscript General Public License for full details.
  11. %
  12. % Everyone is granted permission to copy, modify and redistribute
  13. % Ghostscript, but only under the conditions described in the Ghostscript
  14. % General Public License.  A copy of this license is supposed to have been
  15. % given to you along with Ghostscript so you can know your rights and
  16. % responsibilities.  It should be in a file named COPYING.  Among other
  17. % things, the copyright notice and this notice must be preserved on all
  18. % copies.
  19.  
  20. % Extract the ASCII text from a PostScript file.  Nothing is displayed.
  21. % Instead, ASCII information is written to stdout.  If SIMPLE is defined,
  22. % just the text is written, with a guess at line breaks and word spacing.
  23. % If SIMPLE is not defined, lines are written to stdout as follows:
  24. %
  25. %    F <height> <width> (<fontname>)
  26. %        indicate font height and width of a space
  27. %
  28. %    S <x> <y> (<string>) <width>
  29. %        display a string
  30. %
  31. %    P
  32. %        end of page
  33. % <height> is an integer expressed in tenths of a point
  34. % <width> is an integer in tenths of a point.
  35. % <x> and <y> are integer coordinates, in tenths of a point, with origin
  36. %   at lower left.
  37. % <string> and <fontname> are strings represented with the standard
  38. %   PostScript escape conventions.
  39. % The idea is similar to Glenn Reid's `distillery', only a lot more
  40. % simple-minded, and less robust.
  41.  
  42. % Note that this code will only work in all cases if systemdict is writable
  43. % and if `binding' the definitions of operators defined as procedures
  44. % is deferred.  For this reason, it is normally invoked with
  45. %    gs -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT gs_2asc.ps
  46.  
  47. % Thanks to J Greely <jgreely@cis.ohio-state.edu> for improvements
  48. % to this code.
  49.  
  50. /QUIET true def
  51. systemdict wcheck { systemdict } { userdict } ifelse begin
  52. /SIMPLE dup where { pop true } { false } ifelse def
  53.  
  54. % Disable the display operators.
  55.  
  56. /eofill { newpath } odef
  57. /erasepage { } odef
  58. /fill { newpath } odef
  59. /stroke { newpath } odef
  60.  
  61. % The image operators must read the input, but do nothing.
  62.  
  63. /colorimage { gsave nulldevice //colorimage grestore } odef
  64. /image { gsave nulldevice //image grestore } odef
  65. /imagemask { gsave nulldevice //imagemask grestore } odef
  66.  
  67. % Redefine the end-of-page operators.
  68.  
  69. /copypage { SIMPLE { (\014) } { (P\n) } ifelse //print } odef
  70. /showpage { copypage erasepage initgraphics } odef
  71.  
  72. % Redefine `show'.
  73.  
  74. % Set things up so our output will be in tenths of a point, with origin at
  75. % lower left.  This isolates us from the peculiarities of individual devices.
  76.  
  77. /.show.ident.matrix matrix def
  78. /.show.ident
  79.  { gsave initmatrix
  80.         % Assume the original transformation is well-behaved.
  81.    0.1 0 dtransform abs exch abs max /.show.scale exch def
  82.    0.1 dup scale .show.ident.matrix currentmatrix
  83.    grestore
  84.  } def
  85. /.coord
  86.  { transform .show.ident itransform
  87.    exch round cvi exch round cvi
  88.  } odef
  89. /.dcoord
  90.  {        % Transforming distances is trickier, because
  91.         % the coordinate system might be rotated.
  92.    .show.ident pop
  93.    exch 0 dtransform dup mul exch dup mul add sqrt .show.scale div
  94.    exch 0 exch dtransform dup mul exch dup mul add sqrt .show.scale div
  95.    exch round cvi exch round cvi
  96.  } odef
  97.  
  98. % Define a way to store and retrieve integers that survives save/restore.
  99. /.i.string (                ) def
  100. /.iget { cvi } bind def
  101. /.iput { exch //.i.string exch copy cvs pop } bind def
  102. /.inew { //.i.string length string dup 3 -1 roll .iput } bind def
  103. /.show.x 0 .inew def
  104. /.show.y 0 .inew def
  105. /.show.height 1000 .inew def
  106. % Remember whether the last string ended in a letter and a hyphen.
  107. % (If so, we didn't output the hyphen.)
  108. /.show.hyphen (\000) def
  109.  
  110. % Make sure writing will work even if a program uses =string.
  111. /.show.string =string length string def
  112. /.show.=string =string length string def
  113. /.show==only
  114.  { //=string //.show.=string copy pop
  115.    dup type /stringtype eq
  116.     { dup length //.show.string length le
  117.        { dup rcheck { //.show.string copy } if
  118.        } if
  119.     } if
  120.    //.stdout exch write==only
  121.    //.show.=string //=string copy pop
  122.  } odef
  123.  
  124. /.showfont
  125. %(following comments are from J Greely)
  126. %old code - This didn't work right for me with all fonts.
  127. %
  128. % { 0 currentfont /FontBBox get dup 3 get exch 1 get sub
  129. %   currentfont /FontMatrix get dtransform dtransform
  130. %   exch abs exch abs max round
  131. %   (F ) //print //.stdout exch write==only (\n) //print
  132. % } odef
  133. %
  134. %unfortunately, my way bombs on one of my test files in
  135. %--%show_continue--(?!).  It's from dvi2ps, which molests
  136. %the fonts in some way. --jgreely
  137.  { gsave
  138.     % If we can't get the height and width of the font from
  139.     % the FontBBox, we just measure some characters.
  140.      currentfont /FontBBox known
  141.       { currentfont /FontBBox get } { {0 0 0 0} }
  142.      ifelse
  143.      aload pop exch 4 -1 roll sub 3 1 roll exch sub
  144.      2 copy max 0 ne
  145.       { currentfont /FontMatrix get dtransform
  146.       }
  147.       {    % Unfortunately, charpath is broken in some versions,
  148.     % so we use stringwidth and fudge.
  149.     (X) stringwidth pop dup 1.3 mul
  150.       }
  151.      ifelse .dcoord exch
  152.      currentfont /FontName known
  153.       { currentfont /FontName get } { () }
  154.      ifelse
  155.      dup type /nametype eq { //.show.string cvs } if
  156.    grestore
  157.     % Stack: height width fontname
  158.    SIMPLE
  159.     { pop pop //.show.height exch .iput }
  160.     { (F ) //print 3
  161.        { 2 index .show==only ( ) //print 3 -1 roll } repeat
  162.       pop pop pop (\n) //print
  163.     }
  164.    ifelse
  165.  } odef
  166.  
  167. % Define the letters -- characters which, if they occur followed by a
  168. % hyphen at the end of a line, cause the hyphen and line break
  169. % to be ignored.
  170. /.letter.chars 100 dict def
  171. mark
  172.   65 1 90 { dup 32 add } for
  173. counttomark { StandardEncoding exch get .letter.chars exch dup put } repeat
  174. pop
  175.  
  176. % Define a set of characters which, if they occur at the start of a line,
  177. % are taken as indicating a paragraph break.
  178. /.break.chars 50 dict def
  179. mark
  180.   /bullet /dagger /daggerdbl /periodcentered /section
  181. counttomark { .break.chars exch dup put } repeat
  182. pop
  183.  
  184. % Define character translation to ASCII.
  185. % We have to do this for the entire character set.
  186. /.char.map 500 dict def
  187. /.chars.def { counttomark 2 idiv { .char.map 3 1 roll put } repeat pop } def
  188.     % Encode the printable ASCII characters.
  189. mark 32 1 126
  190.  { 1 string dup 0 4 -1 roll put
  191.    dup 0 get StandardEncoding exch get exch
  192.  }
  193. for .chars.def
  194.     % Encode accents.
  195. mark
  196.   /acute (') /caron (^) /cedilla (,) /circumflex (^)
  197.   /dieresis (") /grave (`) /ring (*) /tilde (~)
  198. .chars.def
  199.     % Encode the ISO accented characters.
  200. mark 192 1 255
  201.  { ISOLatin1Encoding exch get =string cvs
  202.    dup 0 1 getinterval 1 index dup length 1 sub 1 exch getinterval
  203.    .char.map 2 index known .char.map 2 index known and
  204.     { .char.map 3 -1 roll get .char.map 3 -1 roll get concatstrings
  205.       .char.map 3 1 roll put
  206.     }
  207.     { pop pop pop
  208.     }
  209.    ifelse
  210.  }
  211. for .chars.def
  212.     % Encode the remaining standard and ISO alphabetic characters.
  213. mark
  214.   /AE (AE) /Eth (DH) /OE (OE) /Thorn (Th)
  215.   /ae (ae) /eth (dh)
  216.   /ffi (ffi) /ffl (ffl) /fi (fi) /fl (fl)
  217.   /germandbls (ss) /oe (oe) /thorn (th)
  218. .chars.def
  219.     % Encode the other standard and ISO characters.
  220. mark
  221.   /brokenbar (|) /bullet (*) /copyright ((C)) /currency (#)
  222.   /dagger (#) /daggerdbl (##) /degree (o) /divide (/) /dotaccent (.)
  223.   /dotlessi (i)
  224.   /ellipsis (...) /emdash (--) /endash (-) /exclamdown (!)
  225.   /florin (f) /fraction (/)
  226.   /guillemotleft (<<) /guillemotright (>>)
  227.   /guilsingleft (<) /guilsingright (>) /hungarumlaut ("") /logicalnot (~)
  228.   /macron (_) /minus (-) /mu (u) /multiply (*)
  229.   /ogonek (,) /onehalf (1/2) /onequarter (1/4) /onesuperior (1)
  230.   /ordfeminine (-a) /ordmasculine (-o)
  231.   /paragraph (||) /periodcentered (*) /perthousand (o/oo) /plusminus (+-)
  232.   /questiondown (?) /quotedblbase (") /quotedblleft (") /quotedblright (")
  233.   /quotesinglbase (,) /quotesingle (') /registered ((R))
  234.   /section ($) /sterling (#)
  235.   /threequarters (3/4) /threesuperior (3) /trademark ((TM)) /twosuperior (2)
  236.   /yen (Y)
  237. .chars.def
  238.     % Encode a few common Symbol characters.
  239. mark
  240.   /asteriskmath (*) /copyrightsans ((C)) /copyrightserif ((C))
  241.   /greaterequal (>=) /lessequal (<=) /registersans ((R)) /registerserif ((R))
  242.   /trademarksans ((TM)) /trademarkserif ((TM))
  243. .chars.def
  244.  
  245. % Write out a string.  If it ends in a letter and a hyphen,
  246. % don't write the hyphen, and set .show.hyphen to 1;
  247. % otherwise, set .show.hyphen to 0.
  248. /.show.write    % <string>
  249.  { //.show.hyphen 0 0 put
  250.    dup length 2 ge
  251.     { dup dup length 1 sub get 45 eq    % hyphen
  252.        { dup dup length 2 sub get
  253.      currentfont /Encoding get exch get
  254.      //.letter.chars exch known
  255.       {    % Remove the hyphen, and set .show.hyphen
  256.         dup length 1 sub 0 exch getinterval
  257.         //.show.hyphen 0 1 put
  258.       }
  259.      if
  260.        }
  261.       if
  262.     }
  263.    if
  264.     { dup currentfont /Encoding get exch get
  265.       dup //.char.map exch known
  266.        { //.char.map exch get //.stdout exch writestring pop
  267.        }
  268.        { currentfont /Encoding dup StandardEncoding eq
  269.      exch ISOLatin1Encoding eq or
  270.       {    % Untranslated character in standard encoding
  271.         pop //.stdout exch write
  272.       }
  273.       {    % Character in non-standard encoding, substitute
  274.         pop pop //.stdout (*) writestring
  275.       }
  276.      ifelse
  277.        }
  278.       ifelse
  279.     }
  280.    forall
  281.  } odef
  282. /.showstring
  283.  { currentpoint .coord
  284.    3 -1 roll dup stringwidth 1 index 0 rmoveto
  285.    .dcoord pop
  286.     % Stack: x y string width
  287.    SIMPLE
  288.     { 2 index //.show.y .iget ne
  289.        {    % Try to figure out whether we have a line break
  290.         % or a paragraph break.
  291.      2 index //.show.y .iget sub abs
  292.      //.show.height .iget 1.3 mul ge
  293.      2 index length 0 gt
  294.       { 2 index 0 get currentfont /Encoding get exch get
  295.         .break.chars exch known { pop true } if
  296.       }
  297.      if
  298.       { (\n\n)    % Paragraph
  299.       }
  300.       { ( )        % Line
  301.       }
  302.      ifelse //print
  303.      //.show.y 3 index .iput
  304.          //.show.x 4 index .iput
  305.        }
  306.       if
  307.     % If the word processor split a hyphenated word within the same line,
  308.     % put out the hyphen now.
  309.       //.show.hyphen 0 get 0 ne { (-) //print } if
  310.       3 index //.show.x .iget 1 add gt
  311.        { ( ) //print
  312.        }
  313.       if
  314.       4 1 roll .show.write pop add //.show.x exch .iput
  315.     }
  316.     { (S ) //print
  317.       4 -1 roll .show==only ( ) //print
  318.       3 -1 roll .show==only ( ) //print
  319.       exch .show==only ( ) //print
  320.       .show==only (\n) //print
  321.     }
  322.    ifelse
  323.  } odef
  324.      
  325. /show
  326.  { .showfont .showstring
  327.  } odef
  328.  
  329. % Redefine the other string display operators in terms of `show'.
  330.  
  331. /.show1.string ( ) def
  332. /.show1 { //.show1.string exch 0 exch put //.show1.string .showstring } odef
  333. /ashow
  334.  { .showfont
  335.    { .show1 2 copy rmoveto } forall
  336.    pop pop
  337.  } odef
  338. /awidthshow
  339.  { .showfont
  340.     { dup .show1 4 index eq { 4 index 4 index rmoveto } if
  341.       2 copy rmoveto
  342.     }
  343.    forall
  344.    pop pop pop pop pop
  345.  } odef
  346. /widthshow
  347.  { .showfont
  348.    //.show1.string 0 4 -1 roll put
  349.     { //.show1.string search not { exit } if
  350.       .showstring .showstring
  351.       2 index 2 index rmoveto
  352.     } loop
  353.    .showstring pop pop
  354.  } odef
  355. /kshow
  356.  { .showfont
  357.    { .show1 dup exec } forall pop
  358.  } odef
  359.  
  360. % Redirect the printing operators.
  361.  
  362. /.stdout (_temp_.out) (w) file def
  363. /.stderr (_temp_.err) (w) file def
  364. /print { //.stdout exch writestring } odef
  365.  
  366. end
  367.  
  368. % Bind the operators we just defined, and all the others if we didn't
  369. % do it before.  Also reenable 'bind' for future files.
  370.  
  371. .bindoperators
  372. NOBIND currentdict systemdict ne and
  373.  { systemdict begin .bindoperators end }
  374. if
  375. NOBIND
  376.  { /bind /.bind load def }
  377. if
  378.  
  379. % Make systemdict read-only if it wasn't already.
  380.  
  381. systemdict wcheck { systemdict readonly pop } if
  382.